﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace WindowsGame1
{
    class AnimatedSprite
    {
        public Rectangle Rect;
        private readonly Texture2D _idle;
        private readonly Texture2D _run;
        private readonly Texture2D _jump;
       
        private bool _isRunning;
        private bool _isJumping;
        private bool _isRunningRight;
        

        private float _yVelocity;
        private const float MaxYVelocity = 10;
        private float g = 0.2f;

        private int frameWidth;
        private int frameHeight;
        
        public int Frames
        {
            get { return _run.Width/frameWidth; }
        }

        int _currentFrame;
        int _timeElapsed;
        private const int TimeForFrame = 50;

        private GameWorldScreen game;

        public AnimatedSprite(Rectangle rect, Texture2D idle, Texture2D run, Texture2D jump, GameWorldScreen game)
        {
            this.Rect = rect;
            this._idle = idle;
            this._run = run;
            this._jump = jump;
            this.game = game;

            frameWidth = frameHeight = run.Height;
        }

        public void Jump()
        {
            if (!_isJumping && (int)_yVelocity==0)
            {
                _isJumping = true;
                _currentFrame = 0;
                _timeElapsed = 0;
                _yVelocity = MaxYVelocity;
            }

        }

        public void ApplyGravity(GameTime gameTime)
        {
            _yVelocity = _yVelocity - g*gameTime.ElapsedGameTime.Milliseconds/10;
            float dy = _yVelocity*gameTime.ElapsedGameTime.Milliseconds/10;

            Rectangle nextPosition = Rect;
            nextPosition.Offset(0,-(int)dy);

            Rectangle boundingRect = GetBoundingRect(nextPosition);
            if (boundingRect.Top > 0 && boundingRect.Bottom < game.Height 
                && !game.CollidesWithLevel(boundingRect))
                Rect = nextPosition;

            bool colidedOnFallDown = (game.CollidesWithLevel(boundingRect) && _yVelocity < 0);

            if (boundingRect.Bottom >game.Height || colidedOnFallDown)
            {
                _yVelocity = 0;
                _isJumping = false;
            }
        }


        public void StartRun(bool isRight)
        {
            if (!_isRunning)
            {
                _isRunning = true;
                _currentFrame = 0;
                _timeElapsed = 0;
            }
            _isRunningRight = isRight;
        }

        public void Shoot()
        {

        }

        public void Stop()
        {
            _isRunning = false;

        }

        public void Update(GameTime gameTime )
        {
            _timeElapsed += gameTime.ElapsedGameTime.Milliseconds;
            int tempTime = TimeForFrame;

            if (_timeElapsed > tempTime)
            {
                _currentFrame = (_currentFrame + 1) % Frames;
                _timeElapsed = 0;
            }
            if (_isRunning)
            {

                int dx = 3*gameTime.ElapsedGameTime.Milliseconds/10;
                if (!_isRunningRight)
                    dx = -dx;
                Rectangle nextPosition = Rect;
                nextPosition.Offset(dx, 0);

                Rectangle boundingRect = GetBoundingRect(nextPosition);
                Rectangle screenRect = GameWorldScreen.GetScreenRect(boundingRect);

                if (screenRect.Left > 0 && screenRect.Right < game.Width && !game.CollidesWithLevel(boundingRect))
                    Rect = nextPosition;
            }
            ApplyGravity(gameTime);
        }

        Rectangle GetBoundingRect(Rectangle rectangle)
        {
            int width =(int) (Rect.Width*0.4f);
            int x = (int) (rectangle.Left + (Rect.Width*0.2f));

            return new Rectangle(x,rectangle.Top,width,rectangle.Height);
        }

        public void Draw(SpriteBatch spriteBatch)
        {
            Rectangle r = new Rectangle(_currentFrame * frameWidth, 0, frameWidth, frameHeight);
            SpriteEffects effects = SpriteEffects.None; 
            if (_isRunningRight)
                effects = SpriteEffects.FlipHorizontally;

            Rectangle screenRect = GameWorldScreen.GetScreenRect(Rect);

            spriteBatch.Begin(); 
            if (_isJumping)
                spriteBatch.Draw(_jump, screenRect, r, Color.White, 0, Vector2.Zero, effects, 0);
            else
            if (_isRunning)
            {

                spriteBatch.Draw(_run, screenRect, r, Color.White, 0, Vector2.Zero, effects, 0);
            }
            else
            {
                spriteBatch.Draw(_idle, screenRect , Color.White);
            }
            spriteBatch.End();
        }

    } 
}
